Android Profiler Native CPU

Profiler概览

官方教程:https://developer.android.com/studio/profile/android-profiler?hl=zh-CN
Android Profiler提供了CPU,Memory,Network以及Energy等等信息的追踪和分析,此处我们仅关心CPU部分。

CPU Trace

官方教程:https://developer.android.com/studio/profile/cpu-profiler.html?hl=zh-CN#inspect-traces
CPU Trace的部分简单来看分为Java和C/C++(native)两块,Java的部分已经完美集成,所以在这里不做赘述,我们针对Native的部分做一些跳坑指南。

Native Trace相关

函数名和地址的解析

如果需要做详细的trace,必须要保证对应的so库有符号表信息,也就是symbols。

关于符号表的解释:https://blog.csdn.net/wdjjwb/article/details/86233389
简单来说,符号表的意义,就在于把so库内的函数名和对应的0x11223344地址建立联系,方便debug

gdb调试信息

如果需要接gdb这一类调试器,我们需要在编译的时候额外加入一些调试信息,因此在做编译时需要额外带入参数-g,或者是-ggdb,默认是没有调试参数的

gcc -ggdb XXXX.c -o test.out

编译优化

编译优化的作用是对代码的分支,常量以及表达式进行优化,优化可以减小生成的so大小,缩短代码的执行时间,但是同样的,编译优化也会去除一些不必要的信息,比如调试信息,或者是符号表之类的。一般分为四个等级,分别是O0,O1,02,O3,视编译器不同,默认选项也不同,一般为O0O1

gcc -O2 XXXX.c -o test.out

strip

有了以上知识,我们再来看strip,一般来说:

  • 去掉-g,等于程序做了–strip-debug
  • strip程序,等于程序做了–strip-debug和–strip-symbol

有一个简单的方法可以观察当前bin/so是否被strip过,那就是使用file命令:

file XXXXX.so

如果是strip过的文件,在末尾会输出stripped字样:
file_stripped.jpg-29.7kB
反之,如果是未strip过的文件,则会输出not stripped
file_not_stripped.jpg-31.6kB

Android Studio & 编译

增加debug信息,禁止编译优化

具备了以上的知识,针对需要做trace分析的so,我们需要保证它存在symbol信息,同时要避免被strip,因此,为了同时方便debug,我们可以同时加入-g选项。
针对CMakeList.txt

add_compile_options(-ggdb)
add_compile_options(-o0)
add_compile_options.jpg-20.3kB

禁止strip

由于Android Studio会在编译生成apk后,默认会带入一个strip的动作,因此我们需要屏蔽掉这个动作。

packagingOptions{
doNotStrip “*/arm64-v8a/*.so”
}
packagingOptions.jpg-65.1kB

需要注意的是,某些项目中,一些so库会包在aar中一并给到apk去集成,而aar在最终packaging的时候,仍旧是会被解压出来,因此针对这种情况,在引用这个aar包的项目中,也需要做doNotStrip的动作。

packagingOptions{
doNotStrip “*/arm64-v8a/*.so”
}
apk_packagingOptions.jpg-75.4kB

因为此处的abi只用到了arm64,所以仅仅针对arm64-v8a的目录做了doNotStrip的动作。

运行

最后的运行部分是水到渠成的事情了,放几张图感受一下。